home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / LISP / XLISP_TO / MEDICAL_ / ADX.LSP next >
Lisp/Scheme  |  1990-04-21  |  45KB  |  1,233 lines

  1. ;***** XLISP  VERSION 21/04/90 ******
  2.  
  3.  
  4. (defvar *all-dd* nil)
  5. (defvar *all-disease* nil)      ;current dd-structs
  6. (defvar *dd-list* nil)
  7. (defvar *disease-list* nil)    ;current dd's
  8. (defvar *dd-slots* '(symptom diseases d-slot))      ;slots of struct dd
  9. (defvar *symptom-list* nil)                  ;symptoms for search-a-disease
  10. (defvar *probable-diseases* nil)             ;resulting diseases from search
  11. (defvar *age-probable* nil)                  ;diseases within age-group
  12. (defvar *morbidity-list* nil)                ;diseases with morbidity-data
  13. (defvar *disease-slots*                      ;slots of struct disease
  14.       '(name                    ; morbidity geographic-occurrence
  15.         age-groups              
  16.         sex-predominance        ; m 0.6 f 0.4
  17.         clinical-symptoms
  18.         lab-findings            ; labtest: values [no-values] expl cost
  19.         rx-findings             ; Sy : method frequency expl cost
  20.         sites
  21.         therapy                 ; method:dosage time controls complications
  22.         follow-up               
  23.         prognosis-and-complications
  24.         literature              ; ti au publ                                
  25.         diff-diag               ; other diseases: differentiation to act
  26.         general-description
  27.         property-slot
  28.         codes
  29.         reserve1 reserve2 reserve3 reserve4 reserve5))
  30.         
  31. (defvar *prop-list* '(freq explanation methods normal-values cost time
  32.                       morbidity geographic-occurrence dosage 
  33.                       overdose-reactions))     ;possible properties of slots
  34. (defvar *all-symptoms* nil)
  35. (defvar *all-symptoms-string* nil)
  36. (defvar *flag* nil)
  37. (defvar *line-cnt* 0)
  38. (defvar *struct* nil)
  39. (defvar *test-struct* nil)
  40. (defvar *all-string-list* nil)
  41.  
  42.  
  43. (defmacro pop (stack)
  44.   `(let ((x (car ,stack)))
  45.         (setq ,stack (cdr ,stack))
  46.         x))
  47.  
  48. (defmacro push (thing stack)
  49.   `(setq ,stack (cons ,thing ,stack)))
  50.  
  51. ;****** accessors *********
  52. (defmacro symptom (dd) `(car ,dd))
  53. (defmacro diseases (dd) `(car (cdr ,dd)))
  54. (defmacro d-slot  (dd) `(car (cddr ,dd)))
  55.  
  56. (defmacro name (disease) `(car ,disease))
  57. (defmacro age-groups (disease) `(car (cdr ,disease)))
  58. (defmacro sex-predominance (disease) `(car (cddr ,disease))) 
  59. (defmacro clinical-symptoms (disease) `(car (cdddr ,disease)))
  60. (defmacro lab-findings (disease) `(car (cddddr ,disease)))
  61. (defmacro rx-findings (disease) `(car (cdr (cddddr ,disease))))
  62. (defmacro sites (disease) `(car (cddr (cddddr ,disease))))
  63. (defmacro therapy (disease) `(car (cdddr (cddddr ,disease))))
  64. (defmacro follow-up (disease) `(car (cddddr (cddddr ,disease))))
  65. (defmacro prognosis-and-complications (disease)
  66.                                 `(car (cdr (cddddr (cddddr ,disease)))))
  67. (defmacro literature (disease) `(car (cddr (cddddr (cddddr ,disease)))))
  68. (defmacro diff-diag (disease) `(car (cdddr (cddddr (cddddr ,disease)))))
  69. (defmacro general-description (disease)
  70.        `(car (cddddr (cddddr (cddddr ,disease)))))
  71. (defmacro property-slot (disease)
  72.        `(car (cdr (cddddr (cddddr (cddddr ,disease))))))
  73. (defmacro codes (disease)
  74.        `(car (cddr (cddddr (cddddr (cddddr ,disease))))))
  75. (defmacro reserve1 (disease)
  76.        `(car (cdddr (cddddr (cddddr (cddddr ,disease))))))
  77. (defmacro reserve2 (disease)
  78.        `(car (cddddr (cddddr (cddddr (cddddr ,disease))))))
  79. (defmacro reserve3 (disease)
  80.        `(car (cdr (cddddr (cddddr (cddddr (cddddr ,disease)))))))
  81. (defmacro reserve4 (disease)
  82.        `(car (cddr (cddddr (cddddr (cddddr (cddddr ,disease)))))))
  83. (defmacro reserve4 (disease)
  84.        `(car (cdddr (cddddr (cddddr (cddddr (cddddr ,disease)))))))
  85. (defmacro reserve5 (disease)
  86.        `(car (cddddr (cddddr (cddddr (cddddr (cddddr ,disease)))))))
  87. (defmacro prop-symptom (propl) `(car ,propl))
  88. (defmacro prop-property (propl) `(car (cdr ,propl)))
  89. (defmacro prop-value (propl) `(car (cddr ,propl)))
  90.  
  91. (defmacro make-name (&rest args)
  92.  `(intern (format nil "~a" ,@args)))
  93.  
  94. ;******* constructors *********
  95. (defun make-dd () (list () () ()))
  96. (defun make-disease () (list () () () () () 
  97.                              () () () () () 
  98.                              () () () () ()
  99.                              () () () () ()))
  100.  
  101. ;******** menus *********
  102. (defun make-it ()
  103.   (read-in)
  104.   (top-round))
  105.  
  106. (defun top-round ()
  107.   (format t "~%main~%")
  108.   (funcall
  109.       (make-menu '(work-on-dd work-on-diseases work-on-slots
  110.                       general-routines
  111.                       search-and-analyse
  112.                       save-work stop-all))))
  113.      
  114. (defun stop-all () (break))
  115.  
  116. (defun save-work ()
  117.  (save-dd) (save-diseases))
  118.  
  119. (defun work-on-dd ()
  120.   (loop (funcall (make-menu '(show-a-dd show-all-dd 
  121.                                  make-a-dd delete-a-dd clear-dd
  122.                                  make-dd-from-diseases
  123.                                  make-diseases-from-dd
  124.                                  go-back)))))
  125.  
  126. (defun work-on-diseases ()
  127.   (loop (funcall (make-menu '(add-a-disease delete-a-disease
  128.                  change-a-disease find-it change-all-instances
  129.                  set-disease-properties 
  130.                  show-a-disease show-all-diseases show-a-full-disease
  131.                  search-a-disease-incremental
  132.                  go-back)))))
  133.  
  134. (defun work-on-slots ()
  135.   (loop (funcall (make-menu '(add-to-existing-slot delete-slot
  136.                                  collect-and-sort-symptoms find-it
  137.                                  sort-symbols
  138.                                  go-back)))))
  139. (defun general-routines ()
  140.   (loop (funcall (make-menu '(collect-and-sort-symptoms sort-symbols
  141.                                  find-it change-all-instances
  142.                                  print-list-to-file
  143.                                  go-back)))))
  144. (defun search-and-analyse ()
  145.   (loop (funcall (make-menu '(search-a-disease-incremental
  146.                                  difference-analysis
  147.                                  check-the-age-group
  148.                                  print-list-to-file
  149.                                  go-back)))))
  150. (defun go-back () (top-round))
  151.            
  152. ;************ make dd from diseases *****************
  153. ;   checks every symptom in the slots
  154. ;        clinical-findings
  155. ;        lab-findings
  156. ;        rx-findings
  157. ;  adds the name fo a disease to the differential-struct
  158. ;  or builds a new differential-struct
  159.  
  160. (defun make-dd-from-diseases ()
  161.   (let ((d nil) (slots '(clinical-symptoms lab-findings rx-findings)))
  162.     (dolist (structnam *disease-list*)
  163.       (setf d (get-struct *all-disease* structnam 'name))
  164.       (PRINT structnam)
  165.       (dolist (s slots)
  166.         (check-slot s d)))))
  167.      
  168. (defun check-slot (slot dise)
  169.   (let ((vall (get-slot-value slot dise)))
  170.     (cond ((null vall) nil)
  171.           (t (dolist (v (setf vall (make-sure-list vall)))
  172.                (if (member v *dd-list*) (add-dd v dise)
  173.                    (new-dd v dise slot)))))))
  174.  
  175. ;    creates a new differential
  176.                                          
  177. (defun new-dd (sy dis slo)
  178.   (let ((dd (make-dd)))
  179.     (cond ((null sy) nil)
  180.           (t
  181.               (setf *dd-list* (add-to-list *dd-list* sy))
  182.               (setf (symptom dd) sy)
  183.               (setf (diseases dd) (name dis))
  184.               (setf (d-slot dd) slo)
  185.               (setf *all-dd* (add-to-list *all-dd* dd))))))
  186.  
  187. ; adds the disease-name to an existing differential
  188.  
  189. (defun add-dd (sy dis)
  190.   (let ((struct (get-struct *all-dd* sy 'symptom)))
  191.     (if (null struct) (error "discrepancy between *dd-list* and *all-dd"))
  192.     (cond ((null sy) nil)
  193.           (t
  194.               (setf *all-dd* (delete-from-list *all-dd* struct))
  195.               (cond ((null (diseases struct))
  196.                      (setf struct (set-slot-value struct 'diseases (name dis))))
  197.                     ((listp (diseases struct))
  198.                      (if (member (name dis) (diseases struct)) nil
  199.                          (setf struct (set-slot-value struct 'diseases
  200.                                         (cons (name dis) (diseases struct))))))
  201.                     ((atom (diseases struct))
  202.                      (if (equal (name dis) (diseases struct)) nil
  203.                          (setf struct (set-slot-value struct 'diseases
  204.                              (cons (name dis) (list (diseases struct))))))))
  205.               (setf *all-dd* (add-to-list *all-dd* struct))))))
  206.  
  207. ;*********** make-diseases-from-dd *****************
  208. ; makes disease-structs from differentials
  209.  
  210. (defun make-diseases-from-dd ()
  211.   (let ((struct nil))
  212.     (dolist (sym *dd-list*)
  213.       (setf struct (get-struct *all-dd* sym 'symptom))  ;dd-symptom
  214.       (cond ((null struct)
  215.             (format t "~%discrepancy between *disease-list* and *all-disease*"))
  216.             (t (update-diseases-with-dd-symptom struct))))))
  217.  
  218. (defun update-diseases-with-dd-symptom (struct)
  219.   (let ((dis nil))
  220.     (PRINT (SYMPTOM STRUCT))
  221.     (dolist (act-dis (make-sure-list (diseases struct)))
  222.       (setf dis (get-struct *all-disease* act-dis 'name))
  223.       (cond ((null (symptom struct)) nil)
  224.             ((null dis) (new-disease-from-dd 
  225.                       act-dis (symptom struct) (d-slot struct)))
  226.             (t (old-disease-from-dd dis (symptom struct) (d-slot struct)))))))
  227.  
  228. ;   makes a new disease
  229.  
  230. (defun new-disease-from-dd (dis sym sl)
  231.   (let ((str (make-disease)))
  232.     (setf sym (make-sure-list sym))
  233.     (if (null sl) (setf sl 'clinical-symptoms))
  234.     (setf (name str) dis)                       ; set name
  235.     (setf str (set-slot-value str sl sym))      ; set symptom ins slot sl
  236.     (setf *all-disease* (add-to-list *all-disease* str))
  237.     (setf *disease-list* (add-to-list *disease-list*  dis))))
  238.  
  239. ;   adds the symptom to an existing disease-struct
  240.  
  241. (defun old-disease-from-dd (dis sym slot)
  242.   (let ((vall nil))
  243.     (cond ((null sym) nil)
  244.           (t  (if (null slot) (setf slot 'clinical-symptoms))
  245.               (setf vall (get-slot-value slot dis))
  246.               (cond ((null vall)
  247.                      (setf *all-disease* (delete-from-list *all-disease* dis))
  248.                      (setf dis (set-slot-value dis slot (list sym)))
  249.                      (setf *all-disease* (add-to-list *all-disease* dis)))
  250.                     ((listp vall)
  251.                      (if (member sym vall) nil (old-diseases2 dis sym slot)))
  252.                     ((atom vall)
  253.                      (if (equal sym vall) nil (old-diseases2 dis sym slot))) 
  254.                     (t nil))))))
  255.  
  256. (defun old-diseases2 (dis sym slot)
  257.   (let ((vall nil))
  258.     (setf *all-disease* (delete-from-list *all-disease* dis))
  259.     (setf vall (get-slot-value slot dis))
  260.     (setf vall (make-sure-list vall))
  261.     (setf vall (cons sym vall))
  262.     (setf dis (set-slot-value dis slot vall))
  263.     (setf *all-disease* (add-to-list *all-disease* dis))))
  264.  
  265. ;****** find any word in any slot *************
  266.  
  267. (defun find-it ()
  268.   (let ((fi nil))
  269.     (setf *struct* nil)
  270.     (format t "~%FIND~%")
  271.     (setf fi (ask-for-which))
  272.     (find-it-helper *all-disease* *disease-slots* fi)
  273.     (cond ((null *struct*)
  274.            (find-it-helper *all-dd* *dd-slots* fi)
  275.            (cond ((null *struct*) (format t "~%sorry nothing found~%"))
  276.                  (t (format t "~%found it in dd~%"))))
  277.           (t (format t "~%found it in diseases~%")))
  278.     (print-list *struct*)))
  279.  
  280. (defun find-it-helper (struct-list slot-list what)
  281.   (let ((slot-value nil))
  282.     (dolist (dis  (setf struct-list (make-sure-list struct-list)))
  283.       (dolist (slot  (setf slot-list (make-sure-list slot-list)))
  284.         (setf slot-value (get-slot-value slot dis))
  285.         (cond ((null slot-value) nil)
  286.               ((atom slot-value) (if (equal what slot-value) 
  287.                               (setf *struct* (cons (name dis) *struct*))))
  288.               ((listp slot-value) (if (member what slot-value)
  289.                                (setf *struct* (cons (name dis) *struct*)))))))))
  290.  
  291. ;******** disease work **************
  292. ;  database-function  'add
  293.  
  294. (defun add-a-disease ()
  295.   (let ((temp nil) (stemp nil))
  296.     (format t "~%DISEASE - ADD")(terpri)
  297.     (setf temp (ask-for-which))
  298.     (cond ((member temp *disease-list*)(format t "disease exists !"))
  299.           (t  (setf *disease-list* (add-to-list *disease-list* temp))
  300.               (setf stemp (make-disease))
  301.               (setf (name stemp) temp)
  302.               (setf stemp (fill-slots stemp))
  303.               (setf *all-disease* (add-to-list *all-disease* stemp))
  304.               ))))
  305.  
  306. ;   database-function 'delete
  307.  
  308. (defun delete-a-disease ()
  309.   (let ((temp nil))
  310.     (format t "~%DISEASE - DELETE")(terpri)
  311.     (setf temp (ask-for-which))
  312.     (delete-helper temp)))
  313.  
  314. (defun delete-helper (temp)
  315.   (let ((del nil))
  316.    (cond ((not (member temp *disease-list*))
  317.           (format t "disease does not exist !"))
  318.          (t (setf *disease-list* (delete-from-list *disease-list*  temp))
  319.             (setf del (get-struct *all-disease* temp 'name))
  320.             (setf *all-disease* (delete-from-list *all-disease* del))
  321.             ))))
  322.  
  323. ;  database-function 'change
  324.  
  325. (defun change-a-disease ()
  326.   (let ((which nil) (struct nil))
  327.     (format t "~%DISEASE-CHANGE~%")
  328.     (setf which (ask-for-which))
  329.     (cond ((member which *disease-list*)
  330.            (setf struct (get-struct *all-disease* which 'name))
  331.            (format t "~%old values for ~a~%" which)
  332.            (print-disease struct)
  333.            (delete-helper which)
  334.            (change-helper struct)
  335.            (setf *all-disease* (add-to-list  *all-disease* struct))
  336.            (setf *disease-list* (add-to-list *disease-list* (name struct))))
  337.           (t (format t "~%cannot find ~a in disease-list~%" which)))))
  338.  
  339. (defun change-helper (struct)
  340.   (let ((success nil) (oval nil) (slot-contains nil))
  341.     (loop
  342.       (format t "~%value to change (stop with nil) : ")
  343.       (setf success nil)
  344.       (setf oval (read))
  345.       (cond ((null oval) (return struct))
  346.             (t (dolist (sl *disease-slots*)
  347.                  (setf slot-contains (get-slot-value sl struct))
  348.                  (cond ((null slot-contains) nil)
  349.                        ((atom slot-contains)
  350.                         (cond ((equal oval slot-contains)
  351.                                (setf success 'ok)
  352.                                (change-helper2 struct sl slot-contains oval))))
  353.                        ((listp slot-contains)
  354.                         (cond ((member oval slot-contains)
  355.                                (setf success 'ok)
  356.                                (change-helper2 struct sl slot-contains oval)))))
  357.                  (if (equal success 'ok) (return struct))))))))
  358.  
  359. (defun change-helper2 (str sl slc oval)
  360.   (let ((nval nil))
  361.     (progn
  362.       (format t "~%new value for ~a : " oval)  
  363.       (setf nval (read))
  364.       (if (atom slc) (setf slc nval))
  365.       (if (listp slc) (setf slc (cons nval (delete oval slc))))
  366.       (set-slot-value str sl slc)
  367.       str)))
  368.  
  369. ;*********** change-all-instances **************
  370.  
  371. (defun change-all-instances ()
  372. (let ((newvalue nil) (oldvalue nil))
  373.   (format t "~%change all instances")
  374.   (format t "~%old value: ")
  375.   (setf oldvalue (read))
  376.   (cond ((null oldvalue) (return))
  377.         (t (format t "~%new value: ")
  378.            (setf newvalue (read))))
  379.   (cond ((null newvalue) nil)
  380.         (t (change-all-instances-helper oldvalue newvalue
  381.                                 *all-disease* *disease-list* *disease-slots*)
  382.            (change-all-instances-helper oldvalue newvalue
  383.                          *all-dd* *dd-list* *dd-slots*)))))
  384.  
  385. (defun change-all-instances-helper 
  386.               (oldvalue newvalue struct-list name-list slot-list)
  387.   (let ((slot-contains nil) (struct nil))
  388.     (dolist (structnam name-list)
  389.       (setf struct (get-struct struct-list structnam 'name))
  390.       (cond ((null struct) 
  391.              (format t "~%error in change/inst-help ~a~%" structnam))
  392.         (t
  393.           (setf struct-list (delete-from-list struct-list struct))
  394.           (dolist (sl slot-list)
  395.             (setf slot-contains (get-slot-value sl struct))
  396.             (cond ((null slot-contains) nil)
  397.                   ((atom slot-contains) (if (equal slot-contains oldvalue)
  398.                             (setf struct (set-slot-value struct sl newvalue))))
  399.                   ((listp slot-contains) 
  400.                    (if (member oldvalue slot-contains)
  401.                        (setf struct (set-slot-value struct sl
  402.                               (setf slot-contains (cons newvalue 
  403.                                     (delete oldvalue slot-contains)))))))))
  404.           (setf struct-list (add-to-list struct-list struct)))))))
  405.  
  406. ;******* search-a-disease-incremental *********
  407. ; search the database (logical 'and)
  408.  
  409. (defun search-a-disease-incremental ()
  410.   (let ((dd *disease-list*) (ant nil))
  411.     (setf *symptom-list* nil) (setf *probable-diseases* nil)
  412.     (loop
  413.       (format t "~%DD-SEARCH") (terpri)
  414.       (if (atom dd) (format t "~%last disease : ~a" dd)
  415.           (if (< 30 (length dd))
  416.               (format t "~%more than 30 diseases left")
  417.               (format t "remaining diseases ~%~a" dd)))
  418.       (terpri)
  419.       (format t "~%give me a symptom (nil = stop, new = again)~%")
  420.       (setf ant (ask-for-which))
  421.       (cond ((null ant) (setf *probable-diseases* dd) (return))
  422.             ((eql 'new ant)  (setf dd *disease-list* ant nil)
  423.              (setf *symptom-list* nil) (setf *probable-diseases* nil))
  424.             (t  (setf dd (search-helper ant dd 's-and))))
  425.       )))
  426.  
  427. (defun search-helper (ant dd afunc)
  428.   (let ((act nil))
  429.       (cond ((equal ant nil) nil)
  430.             ((member ant *dd-list*)
  431.              (setf *symptom-list* (add-to-list *symptom-list* ant))
  432.              (setf act (get-struct *all-dd* ant 'symptom))
  433.              (cond ((equal (symptom act) ant) 
  434.                     (if (listp (diseases act))
  435.                            (setf dd (funcall afunc dd (diseases act)))
  436.                            (setf dd (diseases act))))
  437.                    (t (format t "~%symptom ~a not equal in struct ~a~%"
  438.                               ant (symptom act)))))
  439.             (t (format t "~%symptom is not in dd-list~%")))
  440.       dd))
  441.  
  442.  
  443. (defun s-and (dd diseases)
  444.   (my-intersection dd diseases))
  445.  
  446. (defun s-or (dd diseases)
  447.   (union dd diseases))
  448.  
  449. (defun s-not (dd diseases)
  450.   (set-difference dd diseases))
  451.  
  452.  
  453. ;******* print functions *********
  454. (defun print-dd (struct)
  455.   (cond ((null struct) (format t "sorry, no dd to print !")(terpri))
  456.         (t  (terpri) (format t "symptom : ~a" (symptom struct))
  457.             (terpri) (format t "diagnoses: ")(terpri)
  458.             (print-list (diseases struct)))))
  459.  
  460. (defun print-to-file (text file)
  461.   (dolist (x text)
  462.     (princ x file) (terpri file)))
  463.  
  464. (defun print-list-to-file ()
  465.   (let ((nam nil) (fp nil) (ll nil))
  466.     (format t "~%filename : ")
  467.     (setf nam (read))
  468.     (format t "~%list : ")
  469.     (setf ll (eval (read)))
  470.     (setf fp (open nam :direction :output))
  471.     (dolist (x (setf ll (make-sure-list ll)))
  472.       (princ x fp) (terpri fp))  
  473.     (close fp)))
  474.  
  475. (defun print-list (l)
  476.   (setf *line-cnt* 0)
  477.   (cond ((null l) (format t "sorry, no list to print !")(terpri))
  478.         ((atom l) (print l) (terpri))
  479.         (t (dolist (x l) (print-and-count-lines x))
  480.            (wait-for-answer)
  481.            (terpri))))
  482.  
  483. (defun print-and-count-lines (lin)
  484.   (cond ((>= *line-cnt* 15)  (wait-for-answer)
  485.          (print lin) (setf *line-cnt* 0))
  486.         (t (print lin) (setf *line-cnt* (+ 1 *line-cnt*)))))
  487.  
  488. (defun wait-for-answer ()
  489.  (read-char))
  490.  
  491. (defun print-disease (struct)
  492.   (let ((ms nil))
  493.     (cond ((null struct) (format t "~%sorry, no disease to print ") (terpri))
  494.           (t   (dolist (m *disease-slots*)
  495.                  (setf ms (get-slot-value m struct))
  496.                  (cond ((null ms) nil) 
  497.                        (t   (terpri)(princ m) (princ " : ")
  498.                             (princ ms))))))
  499.     (terpri)))
  500.  
  501. (defun print-full-disease (struct)
  502.   (cond ((null struct) (format t "~%sorry, no disease to print ") (terpri))
  503.         (t   (dolist (m *disease-slots*)
  504.                (terpri)(princ m) (princ " : ")
  505.                (princ (get-slot-value m struct)))))
  506.   (terpri))
  507.  
  508. ;********* word-root functions *******
  509. ; don't use it on an PC, takes hell of time
  510.  
  511. (defun make-word-root-list ()
  512.   (let ((*all-symptoms* (read-list-from-file "asymptom.txt")))
  513.     (dolist (x *all-symptoms*)
  514.       (checklist x (get-single-words x)))
  515.  (write-list-to-file *word-root-list* "asymptom.rot")))
  516.  
  517. (defun get-single-words (word)
  518.   (let ((wname (symbol-name word)) (word-list nil) (input nil))
  519.     (setf word-list (substitute #\  #\- wname))
  520.     (setf input (make-string-input-stream word-list))
  521.     (do ((x (read input nil) (read input nil))
  522.          (sentence nil))           
  523.         ((not x) (return (reverse sentence)))
  524.       (push x sentence))))
  525.  
  526. (defun checklist (full-word word)
  527.   (let ((struct (get-hlist (car word))))
  528.     (if (null struct) (put-hlist full-word (car word))
  529.          (if (setf struct (checklist2 full-word (make-sure-list struct)))
  530.                           (put-hlist struct (car word))))))
  531.  
  532. (defun checklist2 (full-word struct)
  533.   (dolist (x struct)
  534.     (if (eq x full-word) (return)))
  535.   (setf struct (append (make-sure-list struct) (make-sure-list full-word)))
  536. struct)
  537.  
  538. (defun put-hlist (wlist nkey)
  539.   (let ((temp nil))
  540.   (setf temp (assoc nkey *word-root-list*))
  541.   (setf *word-root-list* (delete-from-list *word-root-list* temp))
  542.   (setf *word-root-list* (add-to-list *word-root-list* 
  543.                              (append (list nkey) (make-sure-list wlist))))))
  544.  
  545. (defun get-hlist (nkey)
  546.   (cdr (assoc nkey *word-root-list*)))
  547.  
  548. ;********* menu /display **************
  549.  
  550. (defun make-menu (li)
  551.   (cond ((null li) nil)
  552.         (t (display-menu li))))
  553.       
  554. (defun display-menu (li)
  555.   (let ((long (length li)))
  556.     (cond ((> long 29) (format t "~%menu with ~a entries too long!~%" long))
  557.           ((> long 15) (display-single-menu li long)) 
  558.           (t           (display-single-menu li long)))))
  559.          
  560. (defun display-single-menu (li long)
  561.   (terpri)
  562.   (dotimes (x long)
  563.     (format t "~%~a     ~a" (1+ x) (nth x li)))
  564.   (get-numbered-answer li long))
  565.      
  566. (defun display-double-menu (li long)
  567.   (let ((half (round (+ 0.5 (/ long 2)))))
  568.     (dotimes (x (1+ half))
  569.       (cond ((null (nth x li)) nil)
  570.             (t (format t "~&~D  ~A~36t" (1+ x) (nth x li))))
  571.       (cond ((null (nth (1+ (+ x half)) li)) nil)
  572.             (t (format t "~D  ~A" (+ 2 (+ x half)) (nth (1+ (+ x half)) li)))))
  573.     (get-numbered-answer li long)))
  574.  
  575. (defun get-numbered-answer (li long)
  576.   (let ((ans nil))
  577.     (format t "~%Enter a number between 1 and ~a~%" long)
  578.     (setf ans (read))
  579.     (cond ((not (numberp ans)) (get-numbered-answer li long))
  580.           ((null ans) (get-numbered-answer li long))
  581.           ((or (< long ans) (> 0 ans)) (get-numbered-answer li long))
  582.           (t (nth (1- ans) li)))))
  583.  
  584. ;******** file functions *********
  585. (defun read-in () (read-diseases) (read-dd)
  586.        (read-symptoms))
  587.  
  588. (defun read-dd ()
  589.   (format t "~%reading dd-files~%")
  590.   (setf *all-dd* (read-list-from-file "dd.txt"))
  591.   (format t "~%constructing *dd-list*~%")
  592.   (setf *dd-list* (get-cars *all-dd*)))
  593.  
  594. (defun save-dd ()
  595.   (format t"~%saving dd-files~%")
  596.   (write-list-to-file *all-dd* "dd.txt"))
  597.  
  598. (defun read-diseases ()
  599.   (format t"~%reading disease-files~%")
  600.   (setf *all-disease* (read-list-from-file "diseases.txt"))
  601.   (format t "~%constructing *disease-list*~%")
  602.   (setf *disease-list* (get-cars *all-disease*)))
  603.  
  604. (defun save-diseases ()
  605.   (format t"~%saving disease-files~%")
  606.   (write-list-to-file *all-disease* "diseases.txt"))
  607.  
  608. (defun read-symptoms ()
  609. (format t"~%reading symptom-files")
  610. (setf *all-symptoms* (read-list-from-file "asymptom.txt"))
  611. (setf *word-root-list* (read-list-from-file "asymptom.rot")))
  612.  
  613. (defun read-list-from-file (filename)
  614. (let ((listname nil)
  615.       (fp (open filename :direction :input)))
  616. (progn
  617.   (do* ((ex nil)
  618.      (ex (read fp) (read fp)))
  619.      ((null ex) (close fp))
  620.  (setf listname (cons ex listname)))
  621.  listname)))
  622.  
  623. (defun write-list-to-file (listname filename)
  624. (let ((listname (make-sure-list listname)) 
  625.       (fp (open filename :direction :output)))
  626. (dolist (x listname)
  627.  (print x fp))
  628. (close fp)))
  629.  
  630. ;******** slot functions *********
  631. ; access and fill the subparts of the disease-struct
  632.  
  633. (defun fill-slots (struct)
  634.   (let ((antw nil) (tx (cons 'return (cdr *disease-slots*))))
  635.     (loop
  636.       (setf antw (make-menu tx))
  637.       (cond ((equal antw 'return) (return struct))
  638.             ((member antw *disease-slots*) 
  639.              (setf struct (put-slot struct antw))) 
  640.             (t (format t "error: non-existing slot in fill-slots !"))))))
  641.  
  642. (defun put-slot (struct antw)
  643.   (let ((temp (make-sure-list (input-list))))
  644.     (set-slot-value struct antw temp)))
  645.  
  646. (defun set-slot-value (struct antw temp)
  647.   (progn
  648.     (case antw
  649.       (name (setf (name struct) temp))      
  650.       (age-groups (setf (age-groups struct) temp))              
  651.       (sex-predominance (setf (sex-predominance struct) temp))
  652.       (clinical-symptoms (setf (clinical-symptoms struct) temp))
  653.       (lab-findings (setf (lab-findings struct) temp))
  654.       (rx-findings (setf (rx-findings struct) temp))
  655.       (sites (setf (sites struct) temp))
  656.       (therapy (setf (therapy struct) temp))
  657.       (follow-up (setf (follow-up struct) temp))
  658.       (prognosis-and-complications 
  659.           (setf (prognosis-and-complications struct) temp))
  660.       (literature (setf (literature struct) temp))
  661.       (diff-diag (setf (diff-diag struct) temp))
  662.       (general-description (setf (general-description struct) temp))
  663.       (property-slot (setf (property-slot struct) temp))
  664.       (codes (setf (codes struct) temp))
  665.       (reserve1 (setf (reserve1 struct) temp))
  666.       (reserve2 (setf (reserve2 struct) temp))
  667.       (reserve3 (setf (reserve3 struct) temp))
  668.       (reserve4 (setf (reserve4 struct) temp))
  669.       (reserve5 (setf (reserve5 struct) temp))
  670. ;(clinical-symptoms-props (setf (clinical-symptoms-props struct) temp))
  671. ;(lab-findings-props (setf (lab-findings-props struct) temp))
  672. ;(rx-findings-props (setf (rx-findings-props struct) temp))
  673.       (symptom (setf (symptom struct) temp))
  674.       (diseases (setf (diseases struct) temp))
  675.       (d-slot (setf (d-slot struct) temp)))
  676.     struct))
  677.  
  678. (defun get-slot-value (antw struct)
  679.   (let ((result nil))
  680.     (progn
  681.       (case antw
  682.         (name (setf result (name struct)))      
  683.         (age-groups (setf result (age-groups struct)))              
  684.         (sex-predominance (setf result (sex-predominance struct)))
  685.         (clinical-symptoms (setf result (clinical-symptoms struct)))
  686.         (lab-findings (setf result (lab-findings struct)))
  687.         (rx-findings (setf result (rx-findings struct)))
  688.         (sites (setf result (sites struct)))
  689.         (therapy (setf result (therapy struct)))
  690.         (follow-up (setf result (follow-up struct)))
  691.         (prognosis-and-complications
  692.             (setf result (prognosis-and-complications struct)))
  693.         (literature (setf result (literature struct)))
  694.         (diff-diag (setf result (diff-diag struct)))
  695.         (general-description (setf result (general-description struct)))
  696.         (property-slot (setf result (property-slot struct)))
  697.         (codes (setf result (codes struct)))
  698.         (reserve1 (setf result (reserve1 struct)))
  699.         (reserve2 (setf result (reserve2 struct)))
  700.         (reserve3 (setf result (reserve3 struct)))
  701.         (reserve4 (setf result (reserve4 struct)))
  702.         (reserve5 (setf result (reserve5 struct)))
  703. ;(clinical-symptoms-props (setf result (clinical-symptoms-props struct)))
  704. ;(lab-findings-props (setf result (lab-findings-props struct)))
  705. ;(rx-findings-props (setf result (rx-findings-props struct)))
  706.         (symptom (setf result (symptom struct)))
  707.         (diseases (setf result (diseases struct)))
  708.         (d-slot (setf result (d-slot struct))))
  709.       result)))
  710.  
  711. (defun input-list ()
  712.   (let ((temp nil))
  713.     (progn
  714.       (format t "~%list-input (terminate with nil):~%")
  715.       (do ((input (read-sentence) (read-sentence)))   ;start
  716.           ((equal nil input)  temp)                  ; end
  717.         (setf temp (append input temp))))))        ;body
  718.  
  719. ; works on a part of a disease-struct
  720. ; 'delete' function
  721.  
  722. (defun delete-slot ()
  723.   (let ((dis nil))
  724.     (format t "~%DISEASE-DELETE-SLOT~%")
  725.     (format t "~%INPUT DISEASE~%")
  726.     (setf dis (ask-for-which))
  727.     (cond ((null dis) nil)
  728.           ((member dis *disease-list*)
  729.            (delete-slot-helper 
  730.                (get-struct *all-disease* dis 'name)))
  731.           (t (format t "~%unknown error in delete-slot ~a~%" dis)))))
  732.  
  733. (defun delete-slot-helper (struct)
  734.   (let ((slot nil) (tempstruct nil))
  735.     (loop
  736.       (format t "~%ACTUAL VALUES~%")
  737.       (print-disease struct)
  738.       (format t "~%INPUT SLOT~%")
  739.       (setf slot (make-menu (cons 'return *disease-slots*)))
  740.       (cond ((equal 'return slot)
  741.              (delete-from-list *all-disease* tempstruct) 
  742.              (setf *all-disease* (add-to-list *all-disease* struct))
  743.              (return))
  744.             (t (setf struct (set-slot-value struct slot nil)))))))
  745.  
  746. ;  works on a part of the disease-struct
  747. ;  'add' function 
  748. (defun add-to-existing-slot ()
  749.   (let ((dis nil))
  750.     (format t "~%DISEASE-ADD-TO-SLOT~%")
  751.     (format t "~%INPUT DISEASE~%")
  752.     (setf dis (ask-for-which))
  753.     (cond ((null dis) nil)
  754.           ((member dis *disease-list*)
  755.            (add-to-existing-slot-helper 
  756.                (get-struct *all-disease* dis 'name)))
  757.           (t (format t "~%unknown error in add-to-existing-slot ~a~%" dis)))))
  758.       
  759. (defun add-to-existing-slot-helper (struct)
  760.   (let ((slot nil) (tempstruct nil))
  761.     (loop
  762.       (format t "~%ACTUAL VALUES~%")
  763.       (print-disease struct)
  764.       (format t "~%INPUT SLOT~%")
  765.       (setf slot (make-menu (cons 'return *disease-slots*)))
  766.       (cond ((equal 'return slot)
  767.              (delete-from-list *all-disease* tempstruct)
  768.              (setf *all-disease* (add-to-list *all-disease* struct))
  769.              (return))
  770.             (t (setf struct (add-to-existing-slot-helper2 slot struct)))))))
  771.        
  772. (defun add-to-existing-slot-helper2 (slot struct)
  773.   (let ((temp nil))
  774.     (format t "~%ACTUAL VALUES FOR SLOT ~a~%" slot)
  775.     (print (get-slot-value slot struct)) (terpri)
  776.         (setf temp (input-list))
  777.     (set-slot-value struct slot (append (get-slot-value slot struct) temp))))
  778.  
  779. ; because the file-save did not work with symbols and properties
  780. ; I put the properties in a special slot of a disease-struct
  781.  
  782. (defun set-disease-properties ()
  783.   (let ((which nil))
  784.     (format t "~%DISEASE-PROPERTIES~%")
  785.     (format t "~%INPUT DISEASE~%")
  786.     (setf which (ask-for-which))
  787.     (cond ((null which) nil)
  788.           ((member which *disease-list*)
  789.            (set-disease-properties-helper
  790.                (get-struct *all-disease* which 'name)))
  791.           (t (format t "~%cannot find ~a in disease-list~%" which)))))
  792.  
  793. (defun set-disease-properties-helper (struct)
  794.   (format t "~%values for ~a~%" (name struct))
  795.   (delete-helper (name struct))
  796.   (setf struct (change-properties struct))
  797.   (setf *all-disease* (add-to-list *all-disease* struct))
  798.   (setf *disease-list* (add-to-list *disease-list* (name struct))))
  799.   
  800. (defun change-properties (struct)
  801.   (let ((slot 'property-slot) (symp nil) (pr nil)
  802.         (val nil) (x nil))
  803.     (loop 
  804.       (print-disease struct)
  805.       (format t"~%symptom :~%")
  806.       (setf symp (read))
  807.       (if (null symp) (return struct))
  808.       (format t "~%property :~%")
  809.       (setf pr (make-menu (cons 'return *prop-list*)))
  810.       (if (equal 'return pr) (return struct))
  811.       (format t "~%property-value for symbol ~a , property ~a.~%" symp pr)
  812.       (setf val (read))
  813.       (if (or (null val) (equal 'return val)) (return struct))
  814.       (setf x (cons (list symp pr val)(get-slot-value slot struct)))
  815.       (setf struct (set-slot-value struct slot x)))))
  816.  
  817. ;******* collecting and sorting **********
  818. ; collects all existing symptoms and writes it to file
  819. ; 'asymptom.txt'
  820.  
  821. (defun collect-and-sort-symptoms ()
  822. (let ((slots '(clinical-symptoms lab-findings rx-findings))
  823.        (dis nil))
  824.   (setf *all-symptoms* '(cough fever))
  825.   (dolist (structnam *disease-list*)
  826.     (setf dis (get-struct *all-disease* structnam 'name))
  827.     (cond ((null dis) (format t "~%discrepancy *all-disease* / *disease-list*~%"))
  828.           (t (do-slots slots dis))))
  829.   (setf *all-symptoms* (sort-them *all-symptoms*))
  830.   (format t "~%writing to symptoms to disk")
  831.   (write-list-to-file *all-symptoms* "asymptom.txt")
  832.   (format t "~%saved symptoms~%")))
  833.  
  834. (defun do-slots (slots dis)
  835. (let ((slot-values nil))
  836.   (dolist (slot slots)
  837.     (setf slot-values (get-slot-value slot dis))
  838.     (cond ((null slot-values) nil)
  839.           (t (do-slot-values slot-values))))))
  840.  
  841. (defun do-slot-values (slot-values)
  842. (let ((slot-values (make-sure-list slot-values)))
  843.   (dolist (sym slot-values)
  844.     (cond ((null sym) nil)          ;empty slot
  845.           ((member sym *all-symptoms*) nil)
  846.           (t (setf *all-symptoms* (cons sym *all-symptoms*)))))))
  847.  
  848.  
  849. ;****** general functions ***************
  850. ; sorts any list of symbols by their 'alphabetic' rank
  851.  
  852. (defun sort-symbols ()
  853.   (let ((lst nil))
  854.     (format t "~%input symbol-list~%")
  855.     (setf lst (read))
  856.     (cond ((member lst '(*all-disease* *all-dd*))
  857.            (format t "~% invalid value"))
  858.           (t (sort-them (eval lst))))))
  859.  
  860. (defun sort-them (sylist)
  861.   (let ((rst nil))
  862.     (progn
  863.       (setf *all-string-list* nil)
  864.       (dolist (x (setf sylist (make-sure-list sylist)))
  865.         (setf *all-string-list* (cons (zap-to-string x) *all-string-list*)))
  866.       (setf *all-string-list* (sort *all-string-list* #'string>))
  867.       (dolist (x (setf *all-string-list* (make-sure-list *all-string-list*)))
  868.         (setf rst (cons (make-name x) rst)))
  869.       rst)))
  870.  
  871.  
  872. ; read an input terminated by 'nil
  873. ; and return the symbols
  874.  
  875. (defun read-sentence ()
  876.   (let ((input nil) (input2 nil))
  877.     (setf input2 (string-trim ".,?!" (read-non-empty-line)))
  878.     (setf input (make-string-input-stream input2))
  879.     (do ((word (read input nil)(read input nil))
  880.          (sentence nil))
  881.         ((not word) (return (reverse sentence)))
  882.       (push word sentence))))
  883.      
  884. ; ask
  885.  
  886. (defun ask-for-which ()
  887.   (format t "~%which one please ?")
  888.   (read))
  889.  
  890. ; if its no list --> then make one
  891.  
  892. (defun make-sure-list (tmp)
  893.   (progn
  894.     (cond ((atom tmp) (setf tmp (list tmp)))
  895.           ((listp tmp) nil)
  896.           (t (format t"~%error making list from ~a~%" tmp)))
  897.     tmp))
  898.  
  899. ; ignore empty inputs
  900.  
  901. (defun read-non-empty-line ()
  902.   (let ((result nil)) 
  903.     (loop
  904.       (setq result (read-line))      (if (= (length result) 0) nil
  905.           (return result)))))
  906.  
  907. ; get the first symbol of every list in a list
  908.  
  909. (defun get-cars (ll)
  910. (let ((res nil))
  911.   (dolist (x ll)
  912.     (setf res (cons (car x) res)))
  913. res))
  914.  
  915. ; Common lisp function
  916.  
  917. (defun remove-duplicates (lsta)
  918. (let ((result nil))
  919.   (dolist (x lsta)
  920.    (cond ((member x result) nil)
  921.          (t (setf result (cons x result)))))
  922. result))
  923.  
  924. ;**** show functions ******
  925. (defun show-a-dd ()
  926.  (print-dd (get-struct 
  927.              *all-dd* (ask-for-which) 'symptom)))
  928. (defun show-all-dd ()
  929.   (print-list *dd-list*))
  930.  
  931. (defun show-a-disease ()
  932.   (print-disease (get-struct *all-disease* (ask-for-which)
  933.                   'name)))
  934. (defun show-a-full-disease ()
  935.   (print-full-disease (get-struct *all-disease* (ask-for-which)
  936.                   'name)))
  937.  
  938. (defun show-all-diseases ()
  939.    (print-list *disease-list*))
  940.  
  941.  
  942. ;********** struct-operations ************
  943. ; accessor for diseases and differentials
  944. ; could be replaced by a hash-list or files or ...
  945. ; as long as every call goes by these functions,
  946. ; the real type of the list is not important and easy to change
  947.  
  948. (defun get-struct (struct-list which slot-name)
  949.   (dolist (m (setf struct-list (make-sure-list struct-list)))
  950.     (if (equal (get-slot-value slot-name m) which) 
  951.         (return m))))
  952.  
  953. (defun delete-from-list (struct-list which)
  954.   (setf struct-list (delete which struct-list)))
  955.  
  956. (defun add-to-list (struct-list what)
  957.   (setf struct-list (cons what struct-list)))
  958.  
  959. ;************** differentials ****************
  960. ;   database-function 'create'
  961.  
  962. (defun make-a-dd ()
  963.   (let ((tt nil) (ddtemp nil))
  964.     (format t "~%Differentials Entry")
  965.     (format t "~%-------------------")
  966.     (terpri)
  967.     (format t "~%DD - Symptom : ")
  968.     (setf tt (read))
  969.     (cond ((null tt) nil)
  970.           ((member tt *dd-list*)
  971.                          (format t "Symptom exists already !"))
  972.           (t (setf *dd-list* (add-to-list *dd-list* tt))
  973.              (setf ddtemp (make-dd)) (setf (symptom ddtemp) tt)
  974.              (setf (diseases ddtemp) (input-dd-diseases))
  975.              (format t "~%slot :~%")
  976.              (setf (d-slot ddtemp) (make-menu *disease-slots*))
  977.              (setf *all-dd* (add-to-list *all-dd*  ddtemp))))))
  978.  
  979. (defun input-dd-diseases ()
  980.   (let ((temp nil))
  981.     (progn
  982.       (format t "~%DD - diseases : ")
  983.       (do ((input (read-sentence) (read-sentence)))     ;start
  984.           ((equal nil input)  (if (atom temp) (list temp))
  985.                                                 temp)   ; end
  986.         (setf temp (append input temp)))                ;body
  987. (if (atom temp) (list temp) temp))))
  988.  
  989. ; database-function 'delete' for differentials
  990.  
  991. (defun delete-a-dd ()
  992.   (let ((del nil) (del2 nil))
  993.     (format t "~%DELETE DD :~%") 
  994.     (setf del (ask-for-which))
  995.     (cond ((member del *dd-list*)
  996.            (setf *dd-list* (delete-from-list *dd-list* del))
  997.            (setf del2 (get-struct *all-dd* del 'symptom))
  998.            (setf *all-dd* (delete-from-list *all-dd* del2)))
  999.           (t (format t "~%unable to delete ~a~%" del)))))
  1000.  
  1001. ; in case you did something wrong
  1002.  
  1003. (defun restore-disease-list ()
  1004.   (setf *disease-list* nil)
  1005.     (setf *disease-list* (get-cars *all-disease*)))
  1006.  
  1007. (defun restore-dd-list ()
  1008.   (setf *dd-list* nil)
  1009.     (setf *dd-list* (get-cars *all-dd*)))
  1010.     
  1011. ;********* analyse search-results ***********
  1012. ; display the difference in symptoms of 2 diseases
  1013. ; the result of the last search is stored in
  1014. ; the symbol *probable-diseases*
  1015.  
  1016. (defun difference-analysis ()
  1017. (let* ((len (length *probable-diseases*))
  1018.        (symptom-array (make-array (* len len)))
  1019.        (place 0) (sx nil))
  1020.                                ;collect-all-symptoms-from-one-disease
  1021. (dolist (dis (setf *probable-diseases* (make-sure-list *probable-diseases*)))
  1022.  (setf sx (collect-symps dis))
  1023.  (setf (aref symptom-array place) sx)
  1024.  (setf place (+ place len)))
  1025. (setf result-array (do-difference symptom-array len))
  1026. (print-result-array *probable-diseases* result-array len)))
  1027.  
  1028. ; print-result of analysis 
  1029.  
  1030. (defun print-result-array (pd res len)
  1031. (let ((start 0) (next -1))
  1032. (dotimes (x (* len len))
  1033.  (setf next (1+ next))
  1034.  (cond ((equal next len) (setf next 0) (setf start (1+ start)))
  1035.        (t  nil))
  1036.   (format t "~%~a differs from  ~a~%" (nth start pd) (nth next pd))
  1037.   (print (aref res x))
  1038.   (format t "~% press any key to continue~%") (wait-for-answer)
  1039.    )))
  1040.  
  1041. (defun do-difference (symptom-array len)
  1042. (let ((r-array (make-array (* len len))) (start nil))
  1043. (progn 
  1044. (dotimes (x len)
  1045.  (setf start (* x len))
  1046.  (dotimes (y len)
  1047.   (setf (aref r-array (+ start y))
  1048.          (set-difference (aref symptom-array start)
  1049.                      (aref symptom-array (* len y))))))
  1050. r-array)))
  1051.  
  1052. (defun collect-symps (nam)
  1053. (let ((rt nil) (temp nil)
  1054.       (slot-list '(clinical-symptoms lab-findings rx-findings))
  1055.       (struct (get-struct *all-disease* nam 'name)))
  1056. (dolist (slot slot-list)
  1057.  (setf temp (get-slot-value slot struct))
  1058.  (if (not (null temp)) (setf rt (append rt temp))))
  1059. rt))
  1060.  
  1061.  
  1062. ;******** analysis v 28/06/89  ***************
  1063. ; does the patient match the age-group of the diseases ?
  1064.  
  1065. (defun check-the-age-group ()
  1066.   (let ((temp-list *probable-diseases*) (age (get-the-age-group))
  1067.         (dis-struct nil) (range nil))
  1068.     (setq *age-probable* nil *no-age* nil *out-of-age* nil)
  1069.     (dolist (dis (setf temp-list (make-sure-list temp-list)))
  1070.       (setf dis-struct (get-struct *all-disease* dis 'name))
  1071.       (setf range (get-slot-value 'age-groups dis-struct))
  1072.       (cond ((null range)
  1073.              (setq *no-age* (cons (name dis-struct) *no-age*)))
  1074.             ((in-range age range)     
  1075.              (setf *age-probable* (cons (name dis-struct) *age-probable*)))
  1076.             (t  (setq *out-of-age* (cons (name dis-struct) *out-of-age*)))))
  1077.     (print-age-results)))
  1078.  
  1079. (defun print-age-results ()
  1080.   (format t "~%continue with <RETURN>~%")
  1081.   (if (null *age-probable*) nil  (print-age-probable))
  1082.   (if (null *no-age*) nil  (print-no-age))
  1083.   (if (null *out-of-age*) nil  (print-out-of-age)))
  1084.  
  1085. (defun print-age-probable ()
  1086.   (format t "~%diseases with congruent age-groups are :~%")
  1087.   (print-list (remove-duplicates *age-probable*))
  1088.   (wait-for-answer))
  1089.  
  1090. (defun print-no-age ()
  1091.   (format t "~%diseases with missing age-groups are :~%")
  1092.   (print-list (remove-duplicates *no-age*))
  1093.   (wait-for-answer))
  1094.  
  1095. (defun print-out-of-age ()
  1096.   (format t "~%diseases outside the current age-groups are :~%")
  1097.   (print-list (remove-duplicates *out-of-age*))
  1098.   (wait-for-answer))
  1099.  
  1100. (defun in-range (age range)          ; missing age-check for weeks/months
  1101.   (do ((age-list range (cddr age-list)))
  1102.       ((null age-list) nil)
  1103.     (cond ((and (>= age (first age-list)) (<= age (second age-list)))
  1104.            (return t))
  1105.           (t nil))))
  1106.  
  1107. (defun get-the-age-group ()
  1108.   (let ((age nil))
  1109.     (format t "~%DISEASE-ANALYSIS~%")
  1110.     (format t "~%input age of patient~%")
  1111.     (setf age (read))
  1112.     (cond ((numberp age) age)
  1113.           (t (get-the-age-group)))))
  1114.  
  1115. ;****** xlisp functions **********
  1116.  
  1117. (defun substitute (new old s &key (test #'eql))
  1118.   (case (type-of s)
  1119.     (string (string:substitute new old s :test test))
  1120.     (cons (subst new old s :test test))
  1121.     ))
  1122.     
  1123. (defun my-intersection (x y)
  1124. (let ((result nil))
  1125.   (dolist (a (make-sure-list x))
  1126.     (if (member a y)
  1127.           (setf result (cons a result))))
  1128.   result))
  1129.  
  1130.  
  1131. (defun set-difference (x y &key (test #'eql))
  1132.   (if x
  1133.       (let*
  1134.        ((uh (car x))
  1135.  (recursion
  1136.           (set-difference (remove uh x :test test)
  1137.                           (remove uh y :test test) :test test)))
  1138.        (if (member uh y :test test)
  1139.     recursion
  1140.     (cons uh recursion)))))
  1141.  
  1142. (defun union (s1 s2 &key (test #'eql))
  1143.   (if s1
  1144.       (adjoin (car s1) (union (cdr s1) s2 :test test) :test test)
  1145.       s2))
  1146.  
  1147. (defun string:substitute (new old string &key (test #'eql))
  1148.   (let ((big (length string)))
  1149.     (if (> big 0)
  1150.         (dotimes (i big string)
  1151.           (let ((c (char string i)))
  1152.             (if (funcall test c old)
  1153.                 (return
  1154.                   (strcat (subseq string 0 i)
  1155.                           (char->string new)
  1156.                           (string:substitute new
  1157.                                              old
  1158.                                              (subseq string (1+ i))))))))
  1159.         string)))
  1160.  
  1161. (defun char->string (c) (string c))
  1162.  
  1163. (setq *declared-globals* nil)
  1164.  
  1165. (defmacro defvar (variable-name &optional value)
  1166.   `(progn
  1167.      (if (not (member ',variable-name *declared-globals*))
  1168.          (push ',variable-name *declared-globals*))
  1169.      (setq ,variable-name ,value)
  1170.      (putprop ',variable-name 'variable 'binding)
  1171.      ))
  1172.  
  1173. (defmacro defconstant (constant-name &optional value)
  1174.   `(progn
  1175.      (if (not (member ',constant-name *declared-globals*))
  1176.          (push ',constant-name *declared-globals*))
  1177.      (setq ,constant-name ,value)
  1178.      (putprop ',constant-name 'constant 'binding)
  1179.      ))
  1180.  
  1181. (defvar *declared-globals*)
  1182.  
  1183.  
  1184. ;******** list / string manipulation ************
  1185. ; copied from Larry Mulcahy UL.ARC
  1186.  
  1187. (defun list-to-string (l)
  1188.   (if (null l)
  1189.       ""
  1190.       (if (equal (length l) 1)
  1191.           (symbol-name (car l))
  1192.           (concatenate 'string
  1193.                        (symbol-name (car l))
  1194.                        " "
  1195.                        (list-to-string (cdr l))))))
  1196.  
  1197. (defun zap-to-string (uh)
  1198.   (cond
  1199.     ((listp uh) (list-to-string uh))
  1200.     ((symbolp uh) (symbol-name uh))
  1201.     ((numberp uh) (number-to-string uh))
  1202.     (t (string uh))))
  1203.  
  1204. (defun list-to-string (ll)
  1205.   (cond ((null ll) "")
  1206.         ((equal (length ll) 1) (zap-to-string (car ll)))
  1207.         (t (concatenate 'string (zap-to-string (car ll)) " "
  1208.                         (list-to-string (cdr ll))))))
  1209.  
  1210. (defun number-to-string (n)
  1211.   (case (type-of n)
  1212.     (float  (if (> (abs n) 100000.0)
  1213.                 (primitive-number-to-string (round n))
  1214.                 (if (< (abs n) 1.0) (format nil "~F" (trim-float n 8))
  1215.                     (format nil "~F" (trim-float n 2)))))
  1216.     (ratio  (if (> (abs n) 100)
  1217.                 (number-to-string (coerce n 'float))
  1218.                 (multiple-value-bind
  1219.                     (whole fraction) (truncate n)
  1220.                   (if (= fraction 0) (format nil "~D" whole)
  1221.                       (format nil "~D-~D" whole fraction)))))
  1222.     (otherwise (primitive-number-to-string n))))
  1223.  
  1224. (defun primitive-number-to-string (n)
  1225.   (let ((stream (make-string-output-stream)))
  1226.     (princ n stream)
  1227.     (get-output-stream-string stream)))
  1228.  
  1229. (defun trim-float (x digits)
  1230.   (let ((magnitude (expt 10 digits)))
  1231.     (/ (fround (* x magnitude)) magnitude)))
  1232.  
  1233.